package hutool工具包学习.EL表达式学习;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.expression.ExpressionUtil;

/**
 * @function mvel表达式工具类
 * @author 肖荣辉
 * @date 2022年6月16日
*/
public class MvelUtils {
	
	/**
	 * @function 执行条件判断的mvel表达式 (若表达式不是条件判断或表达式不正确 ,返回fasle)
	 * @param mvel 表达式
	 * @param contextMap 表达式要执行的上下文map
	 * @author 肖荣辉
	 * @date 2022年6月16日
	*/
	public static boolean evalConditionExpression(String mvelExpression , Map<String , Object> contextMap) {
		
		try {
			
			//若参数不对 , 则直接返回fasle
			if(StrUtil.isBlank(mvelExpression) || contextMap == null) {
				System.out.println("mvel表达式为空或者上下文map为空");
				return false;
			}
			
			Object[] resultArr = (Object[]) ExpressionUtil.eval(mvelExpression, contextMap);
			
			if(resultArr == null || resultArr.length== 0)
				return false;
			
			Object result = resultArr[0];
			
			if(result instanceof Boolean)
				return (Boolean) result;
			
			System.out.println("mvel表达式 : "+mvelExpression+"不是一个条件判断表达式 , 返回fasle");
			
			return false;
			
		} catch (Exception e) {
			System.out.println("mvel表达式执行错误 , 请检查表达式 : " + mvelExpression + " , 是否合法");
			e.printStackTrace();
		}
		
		return false;
	}
	
	/**
	 * @function 从表达式中获取所需要的值(取第一个), 表达式对应map的值必须是一致的,不然就会报错
	 * @param mvel 表达式
	 * @param contextMap 表达式要执行的上下文map
	 * @param clazz 值的类型 (基本类型)
	 * @author 肖荣辉
	 * @date 2022年6月16日
	*/
	@SuppressWarnings("unchecked")
	public static <T> T getEvalFirstValue(String mvelExpression , Map<String , Object> contextMap , Class<T> clazz) {
		
		//若参数不对 , 则直接返回fasle
		if(StrUtil.isBlank(mvelExpression) || contextMap == null) {
			System.out.println("mvel表达式为空或者上下文map为空");
			return null;
		}
		
		Object[] resultArr = (Object[]) ExpressionUtil.eval(mvelExpression , contextMap);
		
		if(resultArr == null || resultArr.length== 0)
			return null;
		
		return (T) resultArr[0];
	}
	
	/**
	 * @function 从表达式中获取所需要的值的集合, 表达式里面的key要和contextMap的key保持一致
	 * @param mvel 表达式
	 * @param contextMap 表达式要执行的上下文map
	 * @param  clazz 值的类型 (基本类型)
	 * @author 肖荣辉
	 * @date 2022年6月16日
	*/
	@SuppressWarnings("unchecked")
	public static <T> List<T> getEvalValueList(String mvelExpression , Map<String , Object> contextMap , Class<T> clazz) {
		
		//若参数不对 , 则直接返回fasle
		if(StrUtil.isBlank(mvelExpression) || contextMap == null) {
			System.out.println("mvel表达式为空或者上下文map为空");
			return null;
		}
		
		Object[] resultArr = (Object[]) ExpressionUtil.eval(mvelExpression , contextMap);
		
		if(resultArr == null || resultArr.length== 0)
			return null;
		
		 List<T> list = new ArrayList<T>();
		
		for(Object object : resultArr ) {
			
			if(object == null)
				continue;
			
			if(object instanceof Collection) {
				list.addAll((Collection<T>) object);
			}else {
				list.add((T) object);
			}
			
		}
		
		return list;
	}
	

}
